// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.ai.states.ZombieIdleState;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.core.logger.ExceptionLogger;
import zombie.debug.DebugLog;
import zombie.iso.IsoChunk;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.iso.SliceY;
import zombie.iso.objects.IsoFireManager;
import zombie.iso.sprite.IsoSpriteInstance;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerMap;

public final class ReanimatedPlayers {
    public static zombie.ReanimatedPlayers instance = new zombie.ReanimatedPlayers();
    private final ArrayList<IsoZombie> Zombies = new ArrayList();

    private static void noise(String string) {
        DebugLog.log("reanimate: " + string);
    }

    public void addReanimatedPlayersToChunk(IsoChunk chunk) {
        int int0 = chunk.wx * 10;
        int int1 = chunk.wy * 10;
        int int2 = int0 + 10;
        int int3 = int1 + 10;

        for (int int4 = 0; int4 < this.Zombies.size(); int4++) {
            IsoZombie isoZombie = (IsoZombie)this.Zombies.get(int4);
            if (isoZombie.getX() >= (float)int0 && isoZombie.getX() < (float)int2 && isoZombie.getY() >= (float)int1 && isoZombie.getY() < (float)int3) {
                IsoGridSquare isoGridSquare = chunk.getGridSquare((int)isoZombie.getX() - int0, (int)isoZombie.getY() - int1, (int)isoZombie.getZ());
                if (isoGridSquare != null) {
                    if (GameServer.bServer) {
                        if (isoZombie.OnlineID != -1) {
                            noise("ERROR? OnlineID != -1 for reanimated player zombie");
                        }

                        isoZombie.OnlineID = ServerMap.instance.getUniqueZombieId();
                        if (isoZombie.OnlineID == -1) {
                            continue;
                        }

                        ServerMap.instance.ZombieMap.put(isoZombie.OnlineID, isoZombie);
                    }

                    isoZombie.setCurrent(isoGridSquare);

                    assert !IsoWorld.instance.CurrentCell.getObjectList().contains(isoZombie);

                    assert !IsoWorld.instance.CurrentCell.getZombieList().contains(isoZombie);

                    IsoWorld.instance.CurrentCell.getObjectList().add(isoZombie);
                    IsoWorld.instance.CurrentCell.getZombieList().add(isoZombie);
                    this.Zombies.remove(int4);
                    int4--;
                    zombie.SharedDescriptors.createPlayerZombieDescriptor(isoZombie);
                    noise("added to world " + isoZombie);
                }
            }
        }
    }

    public void removeReanimatedPlayerFromWorld(IsoZombie zombie) {
        if (zombie.isReanimatedPlayer()) {
            if (!GameServer.bServer) {
                zombie.setSceneCulled(true);
            }

            if (zombie.isOnFire()) {
                IsoFireManager.RemoveBurningCharacter(zombie);
                zombie.setOnFire(false);
            }

            if (zombie.AttachedAnimSprite != null) {
                ArrayList arrayList = zombie.AttachedAnimSprite;

                for (int int0 = 0; int0 < arrayList.size(); int0++) {
                    IsoSpriteInstance isoSpriteInstance = (IsoSpriteInstance)arrayList.get(int0);
                    IsoSpriteInstance.add(isoSpriteInstance);
                }

                zombie.AttachedAnimSprite.clear();
            }

            if (!GameServer.bServer) {
                for (int int1 = 0; int1 < IsoPlayer.numPlayers; int1++) {
                    IsoPlayer isoPlayer = IsoPlayer.players[int1];
                    if (isoPlayer != null && isoPlayer.ReanimatedCorpse == zombie) {
                        isoPlayer.ReanimatedCorpse = null;
                        isoPlayer.ReanimatedCorpseID = -1;
                    }
                }
            }

            if (GameServer.bServer && zombie.OnlineID != -1) {
                ServerMap.instance.ZombieMap.remove(zombie.OnlineID);
                zombie.OnlineID = -1;
            }

            zombie.SharedDescriptors.releasePlayerZombieDescriptor(zombie);

            assert !zombie.VirtualZombieManager.instance.isReused(zombie);

            if (!zombie.isDead()) {
                if (!GameClient.bClient) {
                    if (!this.Zombies.contains(zombie)) {
                        this.Zombies.add(zombie);
                        noise("added to Zombies " + zombie);
                        zombie.setStateMachineLocked(false);
                        zombie.changeState(ZombieIdleState.instance());
                    }
                }
            }
        }
    }

    public void saveReanimatedPlayers() {
        if (!GameClient.bClient) {
            ArrayList arrayList = new ArrayList();

            try {
                ByteBuffer byteBuffer = SliceY.SliceBuffer;
                byteBuffer.clear();
                byteBuffer.putInt(195);
                arrayList.addAll(this.Zombies);

                for (IsoZombie isoZombie0 : IsoWorld.instance.CurrentCell.getZombieList()) {
                    if (isoZombie0.isReanimatedPlayer() && !isoZombie0.isDead() && !arrayList.contains(isoZombie0)) {
                        arrayList.add(isoZombie0);
                    }
                }

                byteBuffer.putInt(arrayList.size());

                for (IsoZombie isoZombie1 : arrayList) {
                    isoZombie1.save(byteBuffer);
                }

                File file = zombie.ZomboidFileSystem.instance.getFileInCurrentSave("reanimated.bin");
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                bufferedOutputStream.write(byteBuffer.array(), 0, byteBuffer.position());
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
            } catch (Exception exception) {
                ExceptionLogger.logException(exception);
                return;
            }

            noise("saved " + arrayList.size() + " zombies");
        }
    }

    public void loadReanimatedPlayers() {
        if (!GameClient.bClient) {
            this.Zombies.clear();
            File file = zombie.ZomboidFileSystem.instance.getFileInCurrentSave("reanimated.bin");

            try {
                FileInputStream fileInputStream = new FileInputStream(file);

                try {
                    BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

                    try {
                        synchronized (SliceY.SliceBufferLock) {
                            ByteBuffer byteBuffer = SliceY.SliceBuffer;
                            byteBuffer.clear();
                            int _int = bufferedInputStream.read(byteBuffer.array());
                            byteBuffer.limit(_int);
                            this.loadReanimatedPlayers(byteBuffer);
                        }
                    } catch (Throwable throwable0) {
                        try {
                            bufferedInputStream.close();
                        } catch (Throwable throwable1) {
                            throwable0.addSuppressed(throwable1);
                        }

                        throw throwable0;
                    }

                    bufferedInputStream.close();
                } catch (Throwable throwable2) {
                    try {
                        fileInputStream.close();
                    } catch (Throwable throwable3) {
                        throwable2.addSuppressed(throwable3);
                    }

                    throw throwable2;
                }

                fileInputStream.close();
            } catch (FileNotFoundException fileNotFoundException) {
                return;
            } catch (Exception exception) {
                ExceptionLogger.logException(exception);
                return;
            }

            noise("loaded " + this.Zombies.size() + " zombies");
        }
    }

    private void loadReanimatedPlayers(ByteBuffer byteBuffer) throws IOException, RuntimeException {
        int int0 = byteBuffer.getInt();
        int int1 = byteBuffer.getInt();

        for (int int2 = 0; int2 < int1; int2++) {
            if (!(IsoObject.factoryFromFileInput(IsoWorld.instance.CurrentCell, byteBuffer) instanceof IsoZombie isoZombie)) {
                throw new RuntimeException("expected IsoZombie here");
            }

            isoZombie.load(byteBuffer, int0);
            isoZombie.getDescriptor().setID(0);
            isoZombie.setReanimatedPlayer(true);
            IsoWorld.instance.CurrentCell.getAddList().remove(isoZombie);
            IsoWorld.instance.CurrentCell.getObjectList().remove(isoZombie);
            IsoWorld.instance.CurrentCell.getZombieList().remove(isoZombie);
            this.Zombies.add(isoZombie);
        }
    }
}
